import ref from 'ref'
import ffi from 'ffi'
import StructType from 'ref-struct'
import FaceBase from './FaceBase'

let AFT_FSDK_Version = StructType({
  lCodebase: FaceBase.MInt32,
  lMajor: FaceBase.MInt32,
  lMinor: FaceBase.MInt32,
  lBuild: FaceBase.MInt32,
  Version: FaceBase.MPChar,
  BuildDate: FaceBase.MPChar,
  CopyRight: FaceBase.MPChar
})

let AFT_FSDK_FACERES = StructType({
  nFace: FaceBase.MInt32,
  rcFace: FaceBase.MIntPtr_t,
  lfaceOrient: FaceBase.MIntPtr_t
})

let LPAFT_FSDK_FACERES = StructType({
  pointer: ref.refType(AFT_FSDK_FACERES)
})

let libname = './libs/libarcsoft_fsdk_face_tracking.dll'
let Library = ffi.Library(libname, {
  'AFT_FSDK_GetVersion': [ref.refType(AFT_FSDK_Version), [FaceBase.MHandleType]],
  'AFT_FSDK_InitialFaceEngine': [FaceBase.MLong, [FaceBase.MPChar, FaceBase.MPChar, FaceBase.MHandleType, FaceBase.MInt32, FaceBase.MHandleRefType, FaceBase.MInt32, FaceBase.MInt32, FaceBase.MInt32]],
  'AFT_FSDK_UninitialFaceEngine': [FaceBase.MLong, [FaceBase.MHandleType]],
  'AFT_FSDK_FaceFeatureDetect': [FaceBase.MLong, [FaceBase.MHandleType, ref.refType(FaceBase.ASVLOFFSCREEN), ref.refType(LPAFT_FSDK_FACERES)]]
})

function detect(hEngine, asvl, result_callback) {
  let pFaceRes = new LPAFT_FSDK_FACERES()
  pFaceRes.pointer = ref.NULL
  let ppFaceRes = pFaceRes.ref()
  // console.log('人脸跟踪数据', asvl.ref())
  let ret = Library.AFT_FSDK_FaceFeatureDetect(hEngine, asvl.ref(), ppFaceRes)
  if (ret !== 0) {
    console.log('AFT_FSDK_FaceFeatureDetect ret: ' + ret)
    result_callback(0, asvl, {nFace: 0, info: []})
  } else {
    let pFaceRes = ppFaceRes.deref()
    let faceRes = pFaceRes.pointer.deref()
    let faces = {}
    faces.nFace = faceRes.nFace
    faces.info = []
    if (faceRes.nFace !== 0) {
      let rect = new FaceBase.MRECT()
      // let orientBuffer = Buffer.alloc(FaceBase.MInt32.size)
      for (let i = 0; i < faceRes.nFace; i++) {
        FaceBase.memcpy(ref.address(rect.ref()), faceRes.rcFace + FaceBase.MRECT.size * i, FaceBase.MRECT.size)
        // FaceBase.memcpy(ref.address(orientBuffer), faceRes.lfaceOrient + FaceBase.MInt32.size * i, FaceBase.MInt32.size)
        // let _orient = orientBuffer.readInt32LE(0)
        let _orient = faceRes.lfaceOrient
        faces.info.push({left: rect.left, top: rect.top, right: rect.right, bottom: rect.bottom, orient: _orient})
      }
    }
    result_callback(0, asvl, faces)
  }
}

exports.AFT_FSDK_GetVersion = Library.AFT_FSDK_GetVersion
exports.AFT_FSDK_InitialFaceEngine = Library.AFT_FSDK_InitialFaceEngine
exports.AFT_FSDK_UninitialFaceEngine = Library.AFT_FSDK_UninitialFaceEngine
exports.AFT_FSDK_FaceFeatureDetect = Library.AFT_FSDK_FaceFeatureDetect
exports.detect = detect
